﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using System.Xml;
using PloobsEngine.Utils;
using PloobsEngine.Cameras;
using PloobsEngine.SceneControl;
using PloobsEngine.Light;
using PloobsEngine.Modelo;

namespace PloobsEngine.Material
{
    public class Material : IMaterial
    {        
        IShader _shader;
        MaterialType type;        

        /// <summary>
        /// Create a Material, Overriding the shader MaterialType
        /// </summary>
        /// <param name="shader"></param>
        /// <param name="type"></param>
        public Material(IShader shader,MaterialType type)
        {
            this.type = type;
            this._shader = shader;
            AffectedByShadow = true;            
        }

        /// <summary>
        /// Create a simple Material
        /// </summary>
        /// <param name="shader"></param>
        public Material(IShader shader)
        {
            this.type = shader.MaterialType;
            this._shader = shader;
            AffectedByShadow = true;
        }

        /// <summary>
        /// Serialization
        /// </summary>
        public Material()
        {
            AffectedByShadow = true;
        }

        #region IMaterial Members

        public void Drawn(GameTime gt, IObject obj, ICamera cam, IList<ILight> lights,IRenderHelper render)
        {            
            _shader.Draw(obj.Modelo,render,cam);
        }

        public virtual void Update(GameTime gametime, IObject obj ,IList<ILight> lights)
        {
            _shader.Update(obj,lights);
        }

        public IShader Shadder
        {
            get
            {
                return _shader;
            }
            set
            {
                _shader = value;
            }
        }

        
        #endregion

        public MaterialType MaterialType
        {
            get
            {
                return type;
            }
            set
            {
                this.type = value;
            }
        }


        #region IMaterial Members

        public virtual void Serialize(System.Xml.XmlTextWriter textWriter)
        {
            SerializerHelper.SerializeNewElement("Shader", textWriter);
            SerializerHelper.SerializeAttributeBaseType<string>(this._shader.GetType().AssemblyQualifiedName, "Type", textWriter);
            this._shader.Serialize(textWriter);
            SerializerHelper.SerializeEndElement(textWriter);


        }

        public virtual void DeSerialize(System.Xml.XmlNode node,EngineStuff engine, IModelo mode)
        {

            XmlElement materialNode = node["Shader"];
            String shaderType = SerializerHelper.DeserializeAttributeBaseType<string>("Type", materialNode);
            if (!String.IsNullOrEmpty(shaderType))
            {
                Type mt = Type.GetType(shaderType);
                IShader shad = Activator.CreateInstance(mt) as IShader;
                shad.DeSerialize(materialNode, engine, null);
                shad.Initialize();
                this.Shadder = shad;
            }           

        }

        #endregion

        #region IMaterial Members


        public void PreDrawnPhase(IWorld mundo,GameTime gt, IObject obj, ICamera cam, IList<ILight> lights, IRenderHelper render)
        {
            _shader.PreDrawPhase(mundo,obj.Modelo,render,cam);
        }

        #endregion

        #region IMaterial Members


        public bool AffectedByShadow
        {
            set;
            get;
        }

        #endregion

        #region IMaterial Members


        public bool isThisMaterialType(MaterialType type)
        {
            if( (type & this.type) == type)
                return true;
            return false;                
        }

        #endregion

        #region IMaterial Members


        public void PosDrawnPhase(GameTime gt, IObject obj, ICamera cam, IList<ILight> lights, IRenderHelper render)
        {
            _shader.PosDrawPhase(obj.Modelo, render, cam,lights);
        }

        #endregion

    }
}
